package org.redxentertainment.videomanager;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;


import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class VideoManager extends Activity implements Runnable {
	
	private static final int MENU_REFRESH			= 1;
	private static final int MENU_ABOUT				= 2;
	private static final int MENU_QUALITY			= 3;
	private static final int MENU_CLEAR				= 4;
	private static final int MENU_CLEAR_QUEUE		= 5;
	private static final int MENU_PLAY_QUEUE		= 6;
	private static final int MENU_SHUFFLE_QUEUE		= 7;
	
	private static final int CONTEXT_ENQUEUE		= 1;
	
	private static final int MSG_UPDATE_THUMB		= 1;
	private static final int MSG_UPDATE_THUMBS		= 2;
	
	private ArrayList<Category> 		categoryArray;
	private ArrayList<Category> 		categoryUpdateArray;
	private ListView					categoryView;
	private CategoryAdapter				categoryAdapter;
	private ProgressDialog				progressDialog;
	private Thread						thread;
	private	Timer						timer;
	private TimerTask					refreshTask;
	
	//-------------------------------------------------------------------------------------
	private Handler messageHandler = new Handler() {

		public void handleMessage(Message msg) {  			
			switch(msg.what) {
				case MSG_UPDATE_THUMB:
					categoryAdapter.remove( (Category) msg.obj );
					categoryAdapter.insert((Category) msg.obj, msg.arg1);
					break;
					
				case MSG_UPDATE_THUMBS:
					categoryAdapter.categories = categoryUpdateArray;
					categoryAdapter.notifyDataSetChanged();
					break;
			}
		}
	};
	
	//-------------------------------------------------------------------------------------
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        categoryArray 		= new ArrayList<Category>();
        categoryUpdateArray = new ArrayList<Category>();
        categoryView 		= (ListView)findViewById(R.id.videoList);
        categoryAdapter 	= new CategoryAdapter(getApplicationContext(), R.layout.category, categoryArray);
        
        categoryView.setAdapter(categoryAdapter);
        categoryView.setOnItemClickListener(clickListener);
        categoryView.setOnCreateContextMenuListener(this);        
        
        IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_FINISHED);
        filter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
        filter.addDataScheme("file");
        registerReceiver(broadcastReceiver, filter);
    }
    
    //-------------------------------------------------------------------------------------
    @Override
    public void onStart() {
        super.onStart();
        
        populate();
        
        thread = new Thread( (Runnable)this );
        thread.start();
        
        timer = new Timer();
        
        refreshTask = new TimerTask() {
    		public void run() {
    			if(! thread.isAlive() ) {
    				thread.run();
    			}
    		}
        };
        
        try {
        	timer.scheduleAtFixedRate(refreshTask, 	2000, 5000);
        } catch(IllegalStateException e) {
        	refreshTask.cancel();
        	timer.purge();
        	timer.scheduleAtFixedRate(refreshTask, 	2000, 5000);
        }
    }
    
    //-------------------------------------------------------------------------------------
    @Override
    public void onDestroy() {
        super.onDestroy();
        
        unregisterReceiver(broadcastReceiver);
    }
    
    //-------------------------------------------------------------------------------------
    @Override
    public void onStop() {
        super.onStop();
        
    }
    
    //-------------------------------------------------------------------------------------
    public void onPause() {
    	super.onPause();
        
    	refreshTask.cancel();
    	timer.cancel();
    	timer.purge();
    }
    
    //-------------------------------------------------------------------------------------
    public void onResume() {
    	super.onResume();
        
    }
    
    //-------------------------------------------------------------------------------------
    @Override
    public void  onSaveInstanceState  (Bundle  icicle) {
    	
    }
    
    //-------------------------------------------------------------------------------------
    public void populate() {
    	String[] categoryProjection = new String[] {
        		"count(1)"
             };
        Category	category;
        Cursor 		categoryCursor;
        
        categoryCursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, categoryProjection, null, null, null);
        
        if(categoryCursor == null) {
        	Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Error!");
			builder.setMessage("Can not access video store!");
			builder.setPositiveButton("ok", null);
			builder.show();
        	return;
        }
        
        categoryAdapter.clear();
        category = new Category();
        categoryCursor.moveToFirst();
        category.name 		= "All Videos";
        category.videos 	= categoryCursor.getInt(0);
        category.thumbnail 	= null;
        categoryAdapter.add(category);
        categoryCursor.close();
        
        categoryProjection = new String[] {
        		"album",
        		"count(1)"
             };
        
        categoryCursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, categoryProjection, "1!=2) GROUP BY (album", null, null);
        
        categoryCursor.moveToFirst();
        while(! categoryCursor.isAfterLast() ) {
        	category = new Category();
        	
        	category.name 	= categoryCursor.getString(0);
        
        	if(category.name == null) {
        		categoryCursor.moveToNext();
        		continue;
        	}
        	
        	category.videos = categoryCursor.getInt(1);
        	
        	
        	
        	categoryAdapter.add(category);
        	
        	categoryCursor.moveToNext();
        }
        categoryCursor.close();
        
        if( categoryAdapter.isEmpty() ) {
        	Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Status");
			builder.setMessage("No video files found!");
			builder.setPositiveButton("ok", null);
			builder.show();
        }
    }
    
    //-------------------------------------------------------------------------------------
    public void run() {
    	String[] previewProjection;
        Category	category;
        Bitmap		thumb;
        Cursor 		previewCursor;
        
        for(int position=0; position < categoryAdapter.getCount(); position++) {
        	category = categoryAdapter.getItem(position);
        
	    	thumb = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + "/video/" + category.name + "/icon.png");
	    	if(thumb != null) {
	    		thumb = Bitmap.createScaledBitmap(thumb, 150, 150, false);
	    		if( thumb.getHeight() > 135 ) {
	    			thumb = Bitmap.createBitmap(thumb, 0, 0, thumb.getWidth(), 135);
	    		}
	    		if( thumb.getWidth() > 145 ) {
	    			thumb = Bitmap.createBitmap(thumb, 0, 0, 145, thumb.getHeight());
	    		}
	    		category.thumbnail = thumb;
	    	} else /*if(! category.name.equals("Camera") )*/ {
	    		previewProjection = new String[] {
	    				MediaStore.Video.Media._ID
	                 };
	            
	            previewCursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, previewProjection, "album=\"" + category.name + "\"", null, "RANDOM()");
	            if(previewCursor != null) {
	            	BitmapFactory.Options options = new BitmapFactory.Options();
	            	options.inSampleSize = 4;
	            	
	            	previewCursor.moveToFirst();
	            	if(! previewCursor.isAfterLast() ) {
	            		thumb = MediaStore.Video.Thumbnails.getThumbnail(getContentResolver(), previewCursor.getInt(0), MediaStore.Video.Thumbnails.MINI_KIND, options);
	            	}
	            	
	            	if(thumb != null) {
	            		if( thumb.getHeight() > 115 ) {
	    	    			thumb = Bitmap.createBitmap(thumb, 0, 0, thumb.getWidth(), 115);
	    	    		}
	    	    		if( thumb.getWidth() > 145 ) {
	    	    			thumb = Bitmap.createBitmap(thumb, 0, 0, 145, thumb.getHeight());
	    	    		}
	            		category.thumbnail = thumb;
	            	}
	            	
	            	previewCursor.close();
	            }
	    	}
	    	
	    	categoryUpdateArray.add(category);
	    	//messageHandler.sendMessage( Message.obtain(messageHandler, MSG_UPDATE_THUMB, position, 0, category) );
        }
        messageHandler.sendMessage( Message.obtain(messageHandler, MSG_UPDATE_THUMBS) );
    }
    
    //-------------------------------------------------------------------------------------
	private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String 	action;
            Intent	mainIntent;
            
            action = intent.getAction();
            
            if( action.compareTo(Intent.ACTION_MEDIA_SCANNER_FINISHED) == 0 ) {
            	if(progressDialog != null) {
            		if( progressDialog.isShowing() ) {
	            		progressDialog.dismiss();
	            		
            		}
            	}
            	mainIntent = new Intent(org.redxentertainment.videomanager.VideoManager.this, org.redxentertainment.videomanager.VideoManager.class);
            	startActivity(mainIntent);
            	finish();
            }
        }
    };
    
    //-------------------------------------------------------------------------------------
    private OnItemClickListener clickListener = new OnItemClickListener() {
        public void onItemClick(AdapterView<?> av, View v, int arg2, long index) {
        	Category category = categoryAdapter.getItem( (int)index );
        	
        	Intent categoryIntent = new Intent(org.redxentertainment.videomanager.VideoManager.this, org.redxentertainment.videomanager.VideoManagerCategory.class);
        	categoryIntent.putExtra("category", category.name);
        	startActivity(categoryIntent);       	
        }
    };
    
  //-------------------------------------------------------------------------------------
    public boolean onCreateOptionsMenu(Menu menu) { 	
        
        menu.add(0, MENU_CLEAR_QUEUE, 	0, "Clear Queue");
			//.setIcon(R.drawable.clear);
        
        menu.add(0, MENU_PLAY_QUEUE, 	0, "Play Queue");
			//.setIcon(R.drawable.play);
        
        menu.add(0, MENU_SHUFFLE_QUEUE, 	0, "Play Queue (Shuffle)");
    		//.setIcon(R.drawable.shuffle);
        
        menu.add(0, MENU_QUALITY, 	0, "Toggle Preview Quality");
			//.setIcon(R.drawable.toggle);
    
        menu.add(0, MENU_CLEAR, 	0, "Clear Play Cache");
			//.setIcon(R.drawable.clear);
        
        menu.add(0, MENU_REFRESH, 	0, "Refresh Media Store");
			//.setIcon(R.drawable.refresh);
        
        return true;
    }
	
    //-------------------------------------------------------------------------------------
    public boolean onOptionsItemSelected(MenuItem item) {
    	VideoDatabase videoDB = new VideoDatabase( getBaseContext() );
    	long id;
    	
        switch (item.getItemId()) {
	        case MENU_REFRESH:
	        	progressDialog = ProgressDialog.show(this, "Android Media Store", "Rescanning SD Card contents...", true, false);
	        	sendBroadcast( new Intent( Intent.ACTION_MEDIA_MOUNTED, Uri.parse( "file://" + Environment.getExternalStorageDirectory() ) ) );
	        	break;
	        	
	        case MENU_ABOUT:
	        	
	        	AlertDialog aboutDialog = new AlertDialog.Builder(this).create();
	        	aboutDialog.setTitle("About");
	        	aboutDialog.setMessage("Author:\n\tDavid McCaffrey\n\tredx entertainment\n\nIcon from Buuf by Mattahan");
	        	aboutDialog.show();
	        	break;
	        	
	        case MENU_QUALITY:
	        	SharedPreferences preferences = getSharedPreferences("main", MODE_PRIVATE);
	        	SharedPreferences.Editor editor = preferences.edit();
	        	
	        	if( preferences.getBoolean("high-quality", true) ) {
	        		Toast.makeText(getApplicationContext(), "Preview quality Set to LOW", Toast.LENGTH_LONG).show();
	        		editor.putBoolean("high-quality", false);
	        		editor.commit();
	        		
	        	} else {
	        		Toast.makeText(getApplicationContext(), "Preview quality Set to HIGH", Toast.LENGTH_LONG).show();
	        		editor.putBoolean("high-quality", true);
	        		editor.commit();
	        	}
	        	break;
	        	
	        case MENU_CLEAR:
	        	videoDB.clearDatabase();
	        	videoDB.close();
	        	break;
	        	
	        case MENU_SHUFFLE_QUEUE:
	        	id = videoDB.dequeueRandom();
	        	while( id != 0) {
	        		playVideo( id );
	        		id = videoDB.dequeueRandom();
	        	}
	        	break;
	        	
	        case MENU_CLEAR_QUEUE:
	        	videoDB.clearQueue();
	        	break;
	        	
	        case MENU_PLAY_QUEUE:       	
	        	id = videoDB.dequeue();
	        	while( id != 0) {
	        		playVideo( id );
	        		id = videoDB.dequeue();
	        	}
	        	break;
	        	
        }
        
        return false;
    }
    
    
    //-------------------------------------------------------------------------------------
    private void playVideo (long id) {
    	Uri				videoUri 	= Uri.withAppendedPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, ""+ id);
    	Intent 			videoPlayer = new Intent(Intent.ACTION_VIEW, videoUri);
    	VideoDatabase 	videoDB 	= new VideoDatabase(getBaseContext());
    	
    	videoDB.setVideoWatched(id);
    	videoDB.close();
    	startActivity(videoPlayer);
    }
    
    //-------------------------------------------------------------------------------------
    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) 
    {
         super.onCreateContextMenu(menu, view, menuInfo);
         menu.add(0, CONTEXT_ENQUEUE, 0, "Queue All");
         
         menu.setHeaderTitle("Options");
    }
 	
    //-------------------------------------------------------------------------------------
    public boolean onContextItemSelected(MenuItem item)
    {   
    	Category		category;
    	VideoDatabase 	videoDB 					= new VideoDatabase( getBaseContext() );
    	AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
    	
    	category = categoryAdapter.getItem(menuInfo.position);
    	
    	switch (item.getItemId()) {
        		
        	case CONTEXT_ENQUEUE:
        		videoDB.enqueueCategory(category.name);
        		break;
        		
    	}
        return true;
    }
    
}